home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 201 / 201.xpi / modules / preallocator.jsm < prev    next >
Text File  |  2010-01-11  |  4KB  |  155 lines

  1. /* You may find the license in the LICENSE file */
  2.  
  3. const EXPORTED_SYMBOLS = [
  4.     'prealloc'
  5. ];
  6.     
  7. const Cc = Components.classes;
  8. const Ci = Components.interfaces;
  9. const Cr = Components.results;
  10. const Cu = Components.utils;
  11. const Exception = Components.Exception;
  12.  
  13. const FileOutputStream = Components.Constructor('@mozilla.org/network/file-output-stream;1', 'nsIFileOutputStream', 'init');
  14. const File = Components.Constructor('@mozilla.org/file/local;1', 'nsILocalFile', 'initWithPath');
  15.  
  16. const log = (function() {
  17.     let logger = Cc['@downthemall.net/debug-service;1'].getService(Ci.dtaIDebugService);
  18.     return function pa_log(msg, ex) {
  19.         if (ex) {
  20.             return logger.log(msg, ex);
  21.         }
  22.         return logger.logString(msg);
  23.     }
  24. })();
  25.  
  26. const SIZE_MIN = 20 * 1024 * 1024; // will not prealloc below
  27. const SIZE_STEP = 10 * 1024 * 1024; // prealloc will NOT use threads up to this size
  28.  
  29. Components.utils.import('resource://dta/cothread.jsm');
  30.  
  31. function prealloc(file, size, perms, callback, tp) {
  32.     tp = !!tp ? tp : {};
  33.     if (size <= SIZE_MIN || !isFinite(size)) {
  34.         if (callback) {
  35.             callback.call(tp, false);
  36.         }
  37.         return null;
  38.     }
  39.     
  40.     //new WorkerJob(file.path, size, perms, callback, tp);
  41.     let rv = new CoThreadListWalker(function() true, realPrealloc(file.clone(), size, perms, callback, tp), 1)
  42.     rv.run();
  43.     return rv;
  44. }
  45.  
  46. function realPrealloc(file, size, perms, callback, tp) {
  47.     let rv = false;
  48.     try {
  49.         for (let ok = true; ok;) {
  50.             let stream = new FileOutputStream(file, 0x02 | 0x08, perms, 0);
  51.             try {
  52.                 let seekable = stream.QueryInterface(Ci.nsISeekableStream);
  53.                 seekable.seek(0x02, 0);
  54.                 let i = Math.min((size - seekable.tell()) - 1, SIZE_STEP);
  55.                 if (i <= 0) {
  56.                     stream.close();
  57.                     break;
  58.                 }
  59.                 seekable.seek(0x01, i);
  60.                 // XXX: This will force the OS to write the file out to this position
  61.                 // However I'm not quite sure yet if this may overwrite already received data
  62.                 // I guess it might (on a very fast connection)
  63.                 // On the other hand, at the moment all IO is running on the main thread
  64.                 // and event execution cannot be "suspended", so we should be safe
  65.                 // "a" is used to avoid sparse file "optimizations"
  66.                 stream.write("a", 1);
  67.                 cont = true;
  68.             }
  69.             catch (ex) {
  70.                 log("prealloc: failed", ex);
  71.                 ok = false;
  72.             }
  73.             stream.close();
  74.             yield true;
  75.         }
  76.         rv = true;
  77.     }
  78.     catch (ex) {
  79.         log("prealloc: Failed to run prealloc worker", ex);
  80.     }
  81.     if (callback) {
  82.         callback.call(tp, rv);
  83.     }
  84. }
  85.  
  86. /*
  87.  * The following code is not in use. Threading will reproducible (but not always) crash the app 
  88.  * 
  89. function WorkerJob(path, size, perms, callback, tp) {
  90.     this.path = path;
  91.     this.size = size;
  92.     this.perms = perms;
  93.     this.callback = callback;
  94.     this.tp = tp;
  95.     
  96.     let tm = Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager);
  97.     this.thread = tm.newThread(0);
  98.     this.main = tm.mainThread;
  99.     this.thread.dispatch(this, this.thread.DISPATCH_NORMAL);
  100. }
  101.  
  102. WorkerJob.prototype = {
  103.     QueryInterface: function worker_QueryInterface(iid) {
  104.         if (iid.equals(Ci.nsISupports) || iid.equals(iid.nsIRunnable)) {
  105.             return this;
  106.         }
  107.         throw Cr.NS_ERROR_NO_INTERFACE;
  108.     },
  109.     run: function worker_run() {
  110.         let rv = false;
  111.         try {
  112.             let file = new File(this.path);
  113.             let stream = new FileOutputStream(file, 0x02 | 0x08, this.perms, 0);
  114.             let seekable = stream.QueryInterface(Ci.nsISeekableStream);
  115.             seekable.seek(0x02, 0);
  116.             let i = seekable.tell() + SIZE_STEP;
  117.             for (i = Math.min(this.size - 1, i); i < this.size - 1; i = Math.min(this.size - 1, i + SIZE_STEP)) {
  118.                 seekable.seek(0x00, i);
  119.                 stream.write("a", 1);
  120.             }
  121.             
  122.             //seekable.setEOF();
  123.             stream.close();
  124.             rv = true;
  125.         }
  126.         catch (ex) {
  127.             log("prealloc: Failed to run prealloc worker", ex);
  128.         }
  129.         this.main.dispatch(new MainJob(this.thread, this.callback, this.tp, rv), this.main.DISPATCH_NORMAL);        
  130.     }
  131. };
  132.  
  133. function MainJob(thread, callback, tp, result) {
  134.     this.thread = thread;
  135.     this.callback = callback;
  136.     this.tp = tp;
  137.     this.result = result;
  138. }
  139. MainJob.prototype = {
  140.     QueryInterface: WorkerJob.prototype.QueryInterface,
  141.     
  142.     run: function main_run() {
  143.         this.thread.shutdown();
  144.         if (this.callback) {
  145.             try {
  146.                 this.callback.call(this.tp, this.result);
  147.                 log("Prealloc done");
  148.             }
  149.             catch (ex) {
  150.                 log("Callback throw", ex);
  151.             }
  152.         }
  153.     }
  154. };
  155. */